package com.qf.cx.simplenms.webservice;

import io.netty.util.internal.SystemPropertyUtil;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.spi.cluster.ClusterManager;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;

public class Monitor extends AbstractVerticle {
    static Logger logger = Logger.getLogger(Monitor.class);
    private long lastReceivedTime = System.currentTimeMillis();
    private String directory;
    private String cmd;

    public Monitor(String directory, String cmd) {
        this.directory = directory;
        this.cmd = cmd;
    }

    @Override
    public void start() {
        vertx.eventBus().consumer("KeepAliveSubject", msg -> {
            lastReceivedTime = System.currentTimeMillis();
            logger.debug("收到心跳");
        });
        checkWorkerStatus();
        vertx.eventBus().consumer("WORKER_DEAD", msg -> {
            logger.error("开始重启");
            try {
                restart();
                vertx.setTimer(30000, l -> {
                    checkWorkerStatus();
                });
            } catch (IOException e) {
                logger.error("启动Worker异常",e);
            }


        });
    }

    public void checkWorkerStatus() {
        vertx.setPeriodic(1000, l -> {
            if ((System.currentTimeMillis() - lastReceivedTime) > 3000) {
                logger.error("Timer no " + l + "工作线程宕机");
                vertx.cancelTimer(l);
                vertx.eventBus().publish("WORKER_DEAD", "");
            }
        });
    }

    private void restart() throws IOException {
        String wholeCmd = directory + File.separator + cmd;
        Process process = Runtime.getRuntime().exec("cmd /c start " + cmd, new String[]{}, new File(directory));
    }
    public static void main(String[] args) {
        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);
        Monitor monitor = new Monitor(args[0],args[1]);
        Vertx.clusteredVertx(options, ret -> {
            if (ret.succeeded()) {
                Vertx vertx = ret.result();
                vertx.deployVerticle(monitor, new DeploymentOptions().setInstances(1).setWorker(true));
            } else {
                throw new RuntimeException("Monitor start failed");
            }
        });
    }
}